package com.sanri.test.jgit;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.RenameDetector;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class GitMain {

    /**
     * 底层 api  git 分为底层 api 和高层 api 两种, 底层使用麻烦,但更细节,高层使用简单,一般使用高层的 api 即可
     * http://doc.yonyoucloud.com/doc/wiki/project/pro-git-two/jgit.html
     * @throws IOException
     */
    @Test
    public void testCommitsV() throws IOException {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        builder.findGitDir(new File(System.getProperty("user.dir")));
        Repository repository = builder.build();
        String branch = repository.getBranch();
        System.out.println(branch);
    }

    /**
     * 高层 api
     * @throws IOException
     * @throws GitAPIException
     */
    @Test
    public void testCommits() throws IOException, GitAPIException {
        Git git = Git.open(new File(System.getProperty("user.dir")));
        Iterable<RevCommit> revCommits = git.log().call();
        Iterator<RevCommit> iterator = revCommits.iterator();
        while (iterator.hasNext()){
            RevCommit revCommit = iterator.next();
            String commitId = revCommit.getName();
            Date commitTime = revCommit.getAuthorIdent().getWhen();
            String name = revCommit.getAuthorIdent().getName();
            String fullMessage = revCommit.getFullMessage();
            System.out.println(commitId+","+name+" 在 "+ DateFormatUtils.ISO_DATETIME_FORMAT.format(commitTime)+" 提交信息为 :"+fullMessage);
        }
    }

    @Test
    public void testDiffBetweenCommit() throws IOException, GitAPIException {
        // 打开一个存在的仓库
        Repository repository = new FileRepositoryBuilder()
                .findGitDir(new File(System.getProperty("user.dir")))
                .build();

        ObjectId oldHead = repository.resolve("HEAD^^^^{tree}");
        ObjectId head = repository.resolve("HEAD^{tree}");

        try (ObjectReader reader = repository.newObjectReader()) {
            CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
            oldTreeIter.reset(reader, oldHead);
            CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
            newTreeIter.reset(reader, head);

            // finally get the list of changed files
            try (Git git = new Git(repository)) {
                List<DiffEntry> diffs = git.diff()
                        .setNewTree(newTreeIter)
                        .setOldTree(oldTreeIter)
                        .call();
                for (DiffEntry entry : diffs) {
                    System.out.println("Entry: " + entry);
                }
            }
        }
    }

    /**
     * https://blog.csdn.net/qq_42331185/article/details/96111550
     * @throws IOException
     * @throws GitAPIException
     */
    @Test
    public void getVersionFiles() throws IOException, GitAPIException {
        String commitId = "d7eacb7daeecdd326b0d4660f3fa93529b28b5d9";
        Git git = Git.open(new File(System.getProperty("user.dir")));
        Repository repository = git.getRepository();
        ObjectId resolve = repository.resolve(commitId);

        Iterable<RevCommit> allCommitsLater = git.log().add(resolve).call();
        Iterator<RevCommit> iterator = allCommitsLater.iterator();
        while(iterator.hasNext()){
            RevCommit next = iterator.next();
            String name = next.getName();
            String author = next.getAuthorIdent().getName();
            Date commitTime = next.getAuthorIdent().getWhen();
            String fullMessage = next.getFullMessage();
            System.out.println(name+"|"+author+"|"+ DateFormatUtils.ISO_DATETIME_FORMAT.format(commitTime)+"|"+fullMessage);
        }
        RevCommit commit = iterator.next();

        // 给存储库创建一个树的遍历器
        TreeWalk tw = new TreeWalk(repository);
        // 将当前commit的树放入树的遍历器中
        tw.addTree(commit.getTree());

        commit = iterator.next();
        if (commit != null) {
            tw.addTree(commit.getTree());
        } else {
//            return null;
        }

        tw.setRecursive(true);
        RenameDetector rd = new RenameDetector(repository);
        rd.addAll(DiffEntry.scan(tw));
        //获取到详细记录结果集    在这里就能获取到一个版本号对应的所有提交记录（详情！！！）
        List<DiffEntry> list = rd.compute();

        for (DiffEntry diffEntry : list) {
            System.out.println(diffEntry);
        }
    }

    @Test
    public void test() throws IOException {
    }
}
